defmodule Plausible.CustomerSupport.EnterprisePlan do
  @moduledoc """
  Custom plan price estimation
  """
  @spec estimate(Keyword.t()) :: Decimal.t()
  def estimate(basis) do
    basis =
      Keyword.validate!(basis, [
        :billing_interval,
        :pageviews_per_month,
        :sites_limit,
        :team_members_limit,
        :api_calls_limit,
        :features,
        :managed_proxy_price_modifier
      ])

    pv_rate =
      pv_rate(basis[:pageviews_per_month])

    sites_rate =
      sites_rate(basis[:sites_limit])

    team_members_rate = team_members_rate(basis[:team_members_limit])

    api_calls_rate =
      api_calls_rate(basis[:api_calls_limit])

    features_rate =
      features_rate(basis[:features])

    cost_per_month =
      Decimal.from_float(
        (pv_rate +
           sites_rate +
           team_members_rate +
           api_calls_rate +
           features_rate + managed_proxy_price_modifier(basis[:managed_proxy_price_modifier])) *
          1.0
      )
      |> Decimal.round(2)

    if basis[:billing_interval] == "monthly" do
      cost_per_month
    else
      cost_per_month |> Decimal.mult(10) |> Decimal.round(2)
    end
  end

  def managed_proxy_price_modifier(true), do: 199.0
  def managed_proxy_price_modifier(_), do: 0

  def pv_rate(pvs) when pvs <= 10_000, do: 19
  def pv_rate(pvs) when pvs <= 100_000, do: 39
  def pv_rate(pvs) when pvs <= 200_000, do: 59
  def pv_rate(pvs) when pvs <= 500_000, do: 99
  def pv_rate(pvs) when pvs <= 1_000_000, do: 139
  def pv_rate(pvs) when pvs <= 2_000_000, do: 179
  def pv_rate(pvs) when pvs <= 5_000_000, do: 259
  def pv_rate(pvs) when pvs <= 10_000_000, do: 339
  def pv_rate(pvs) when pvs <= 20_000_000, do: 639
  def pv_rate(pvs) when pvs <= 50_000_000, do: 1379
  def pv_rate(pvs) when pvs <= 100_000_000, do: 2059
  def pv_rate(pvs) when pvs <= 200_000_000, do: 3259
  def pv_rate(pvs) when pvs <= 300_000_000, do: 4739
  def pv_rate(pvs) when pvs <= 400_000_000, do: 5979
  def pv_rate(pvs) when pvs <= 500_000_000, do: 7459
  def pv_rate(pvs) when pvs <= 1_000_000_000, do: 14_439
  def pv_rate(_), do: 14_439

  def sites_rate(n) when n <= 50, do: 0
  def sites_rate(n), do: n * 0.1

  def team_members_rate(n) when n > 10, do: (n - 10) * 15
  def team_members_rate(_), do: 0

  def api_calls_rate(n) when n <= 600, do: 0
  def api_calls_rate(n) when n > 600, do: round(n / 1_000) * 100

  @feature_rates %{
    "sites_api" => 99,
    "sso" => 299
  }

  def features_rate(features) do
    features
    |> Enum.map(&Map.get(@feature_rates, &1, 0))
    |> Enum.sum()
  end
end
